import type { HitRecord } from "./hitUtil"
import { dot, type Vec3 } from "./vectorUtil"

/**
 * 光线类
 */
export class Ray {
  /** 光线原点 */
  origin: Vec3
  /** 光线方向 */
  direction: Vec3

  constructor(origin: Vec3, direction: Vec3) {
    this.origin = origin
    this.direction = direction
  }

  /**
   * 光线沿着方向前进一定时间之后的点
   * @param t 
   * @returns 
   */
  getPoint(t: number) {
    return this.origin.add(this.direction.mul(t))
  }

  /**
   * 在交互点反射
   * @param hit 
   * @returns 
   */
  reflect(hit: HitRecord) {
    // 生成新的反射光线，源来自于反射点
    return new Ray(hit.point, reflect(this.direction.unitVec(), hit.normal))
  }
}


/**
 * 光线反射
 * @param v 入射向量单位向量，入射点到反射点
 * @param normal 法向量单位向量 中心到反射点
 * @returns 出射向量单位向量 反射点到出射点
 */
export function reflect(v: Vec3, normal: Vec3) {
  // 先求出入射光线延法线方向的分向量，
  //    点积得到的是法线分量的长度
  //    法向量乘以2倍长度
  // 然后入射光线减去两倍这个分向量的值就是反射光方向
  return v.sub(normal.mul(dot(v, normal) * 2))
}